package com.quectel.emp.controller.device;

import cn.hutool.core.lang.func.LambdaUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.quectel.business.dms.device.DeviceBusiness;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.dept.dto.DeptPersonDto;
import com.quectel.core.module.device.dto.DeviceColumnDto;
import com.quectel.core.module.device.dto.DeviceDto;
import com.quectel.core.module.device.dto.datav.DeviceCountDto;
import com.quectel.core.module.device.dto.mongo.MongoDeviceAlarmLogDto;
import com.quectel.core.module.device.service.DeviceColumnService;
import com.quectel.core.module.device.service.DeviceService;
import com.quectel.core.module.device.service.mongo.MongoDeviceService;
import com.quectel.emp.controller.BaseController;
import com.quectel.emp.util.SessionHolder;
import com.quectel.emp.vo.device.DeviceInfoVo;
import com.quectel.util.common.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author rananxin
 * @email ryan.ran@quectel.com
 * @date 2022/6/6 10:33
 */
@RestController
@RequestMapping("deviceManager")
@Tag(name = "DeviceManagerController", description = "设备管理相关的api")
public class DeviceManagerController extends BaseController {

    @Autowired
    private DeviceBusiness deviceBuisiness;
    @DubboReference
    private DeviceService deviceService;
    @DubboReference
    private MongoDeviceService mongoDeviceService;
    @DubboReference
    private DeviceColumnService deviceColumnService;

    @GetMapping("getKeys")
    @Operation(summary = "获取已绑定的门禁列表")
    public Response<Object> getKeys() {
        SessionHolder.checkEmp();
        DeptPersonDto emp = SessionHolder.getEmp();

        List<DeviceDto> deviceDtos = deviceBuisiness.queryAuthEntranceGuardByPerson(SystemConstants.STAFF, emp.getId());
        return Response.ok().wrap(deviceDtos);
    }

    @PostMapping("openDoor")
    @Operation(summary = "远程开门")
    public Response<Object> openDoor(@RequestBody Long deviceId) {
        // 校验权限
        // 调用门禁抽象类openDoor
        return Response.ok();
    }

    @GetMapping("countDevice")
    @Operation(summary = "设备统计")
    public Response<DeviceCountDto> countDevice(
            @Parameter(description = "设备类型id") @RequestParam(required = false) Long deviceCategoryId) {
        SessionHolder.checkEmp();
        DeptPersonDto emp = SessionHolder.getEmp();

        Map<String, Object> params = new HashMap<>();
        params.put(LambdaUtil.getFieldName(DeviceDto::getVillage), emp.getVillageId());
        params.put(LambdaUtil.getFieldName(DeviceDto::getDeviceCategoryId), deviceCategoryId);

        DeviceCountDto deviceCountDto = deviceService.countDevice(params);
        return Response.<DeviceCountDto>ok().wrap(deviceCountDto);
    }

    @GetMapping("list")
    @Operation(summary = "根据条件查询设备分页列表")
    public Response<Page<DeviceDto>> list(
            @Parameter(description = "搜索框输入内容:模糊匹配 名称,imei,地址,deviceCode") @RequestParam(required = false) String queryString,
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize,
            @Parameter(description = "在线状态 0离线 1在线") @RequestParam(required = false) Byte onlineStatus,
            @Parameter(description = "告警状态 0正常 1告警") @RequestParam(required = false) Byte alarmStatus
    ) {
        SessionHolder.checkEmp();
        DeptPersonDto emp = SessionHolder.getEmp();

        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        assert emp != null;
        request.put(LambdaUtil.getFieldName(DeviceDto::getVillage), emp.getVillageId());
        int total = deviceService.queryTotal(request.getParams());

        List<DeviceDto> list = null;
        if (total > 0) {
            list = deviceService.queryListLessPadding(request.getParams());
        } else {
            list = new ArrayList<>();
        }

        Page<DeviceDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<DeviceDto>>ok().wrap(page);
    }

    @GetMapping("alarmLog")
    @Operation(summary = "告警日志分页列表")
    public Response<Page<MongoDeviceAlarmLogDto>> alarmLog(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize,
            @Parameter(description = "开始时间") @RequestParam(required = false) String startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) String endTime,
            @Parameter(description = "设备id") @RequestParam Long deviceId
    ) {
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        int total = mongoDeviceService.queryDeviceAlarmLogTotal(request.getParams());
        List<MongoDeviceAlarmLogDto> mongoDeviceAlarmLogDtos = new ArrayList<>();
        if (total > 0) {
            mongoDeviceAlarmLogDtos = mongoDeviceService.queryDeviceAlarmLog(request.getParams());
        }
        Page<MongoDeviceAlarmLogDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, mongoDeviceAlarmLogDtos);
        return Response.<Page<MongoDeviceAlarmLogDto>>ok().wrap(page);
    }

    /**
     * 根据id查询单条记录
     */
    @GetMapping("info/{id}")
    @Operation(summary = "根据id查询设备管理单条记录")
    public Response<DeviceDto> info(@PathVariable("id") Long id) {
        SessionHolder.checkEmp();

        DeviceDto deviceDto = deviceService.selectById(id);
        DeviceInfoVo deviceInfoVo = CopyUtils.copyObj(deviceDto, DeviceInfoVo.class);

        if (StringUtils.isNotBlank(deviceDto.getLastData())) {
            JsonNode dataJson = JacksonUtils.parse(deviceDto.getLastData(), JsonNode.class);
            final JsonNode finalData = dataJson;
            List<DeviceColumnDto> deviceColumnDtos = deviceColumnService.selectByDeviceTypeId(deviceDto.getDeviceTypeId());
            List<DeviceInfoVo.DataInfo> lastData = deviceColumnDtos.stream().map(o -> {
                DeviceInfoVo.DataInfo dataInfo = new DeviceInfoVo.DataInfo();
                dataInfo.setKey(o.getEntityName());
                dataInfo.setKeyCnName(o.getCnName());
                dataInfo.setUnit(o.getUnit());

                String v = String.valueOf(finalData.get(o.getEntityName()));
                if (DeviceColumnDto.FieldTypeEnum.ENUM.getType().equals(o.getFieldType())) {
                    if (StringUtils.isNotBlank(o.getFieldDictJson())) {
                        JsonNode dictJson = JacksonUtils.parse(o.getFieldDictJson(), JsonNode.class);
                        String realValue = dictJson.get(v).asText();
                        dataInfo.setRealValue(realValue);
                    }
                } else {
                    dataInfo.setRealValue(v);
                }

                return dataInfo;
            }).collect(Collectors.toList());
            deviceInfoVo.setLastDataInfo(lastData);
        }

        return Response.<DeviceDto>ok().wrap(deviceInfoVo);
    }


}
